home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / 3dvect37.zip / 3D.DOC next >
Text File  |  1994-06-22  |  30KB  |  564 lines

  1.  
  2.     "Knowledge is Power, Power is Money"
  3.  
  4.     3d Vectors Source
  5.  
  6.      by John McCarthy (with a little help from his mommy:eg food)
  7.         1316 Redwood Lane
  8.         Pickering, Ontario, Canada
  9.         L1X 1C5
  10.  
  11.        (905) 831-1944 (voice, always willing to talk, but do not call at 2am)
  12.  
  13.     Documentation is in  no  defined  order. Sorry, I just  sorta  lumped  my
  14.     ideas together and ended up with this file.
  15.  
  16.     Routines support any  x mode, - but  page  flipping  is  not  allowed  in
  17.     resolutions which allow only 1 page - see "pages" constant.
  18.  
  19.     Full clipping is  performed  to  user  defind  areas - see  constants  in
  20.     equ.inc. They have   been   changed  to  memory  locations  for  variable
  21.     windowing or multiple screens.  For  windowing,  the last z locations for
  22.     that window must be remembered along with a slew of other  locations, see
  23.     vars.inc for that  info.  To change a window, save the lastz information,
  24.     reset with old lastz information and  then  call  set_clip  to change the
  25.     border clipping and screen center data.
  26.  
  27.     The theoretical screen  is  considered  to be (x,y) with  0,0  being  the
  28.     center of the  screen!.   So  -100,-100  is  somewhere  on  the top left!
  29.     actual screen goes from (0,0) to (320,200)  -  or  whatever mode size you
  30.     select.  Matt Pritchard's routines (xmode.asm) assume  0,0  to be the top
  31.     left of the  screen  while  my routines (me = John = 3d.asm) consider the
  32.     screen center to be the constants xcenter and ycenter.
  33.  
  34.     Visible space is  -4628196  to +4628196  on  all  axis  (approx).  Object
  35.     locations are 32 bit, vector routines are 16 bit, objects must be smaller
  36.     than 16 bit but are visable within about a 32 bit range.   (4 million, as
  37.     it is now,  is  very  very  far).   Since the camera is always at (0,0,0)
  38.     (relative), objects with (relative) negative z values are not seen.  This
  39.     cuts the z space to 0 to 4mil.  Visible space is always divided by 256 so
  40.     decimals can be allowed in adding, and  moving of objects.  Visible space
  41.     therefore, is actually  from -1.024 billion to +1.024  billion  with  the
  42.     lower byte having  no effect on the location.  Non-visible space is where
  43.     objects can be but won't appear on screen.   This space is a 256 *256*256
  44.     cube.  To racap:  you have 32 bit x,y,z axis with a visual  range  of  28
  45.     bits, where the  lower  8  bits don't affect the location.  (Lower 8 bits
  46.     don't count because locations are shr'ed)   i  say that the visable space
  47.     is "about" 4mil only because of the code in the make3d routine: this code
  48.     multiplies by a  constant  and then performs divide by  z  distance.   We
  49.     cannot allow the  multiply  to  overflow  and  therfore must truncate our
  50.     maximum distance to prevent this.  The  constants  for multiplication are
  51.     the screen ratio constants and the calculation to test for an overflow is
  52.     as such -2^32/2/256/(largest constant).  The constant I  have used is 464
  53.     for the y  ratio.   I  have  used  this  because  of my desire to use the
  54.     320x400 mode resolution.  Therfore, 4.3gig/2/256/464  = about 4 million -
  55.     our maximum visual  distance.  Like, trust me, you don't  really  need  a
  56.     larger universe.  Fixing  the  make  3d  routine  wont  allow  you to see
  57.     farther because then you would have to fix the rotate routine, etc, etc.
  58.  
  59.      When defining a location: ebx = x, ecx = y, ebp = z
  60.      When defining a rotation: x = pitch, y = heading, z = yaw
  61.      si refers to object number, di refers to time.
  62.  
  63.      Rotations occure in order:
  64.      zobject,xobject,yobject,ycamera,xcamera,zcamera - rotations are
  65.      compounded in matrix for faster computation.
  66.  
  67.      Vmatrix is the matrix for object rotation.  Ematrix is  the  matrix  for
  68.      camera rotation.   If  you want know where a point in space will show up
  69.      on the screen, load ebx, ecx, ebp with your x,y,z point, subtract camera
  70.      location and  call erotate (eye rotate).   The  point  will  be  rotated
  71.      according to current camera angles.  Make sure that a call to setsincose
  72.      has taken place to set the eye rotation matrix (ematrix).
  73.  
  74.      Polygon can handle any number of sides.  To draw a triangle,  make  last
  75.      point equal  to first point, eg 1,4,5,1. Number of sides of a polygon is
  76.      determined so that the polygon is  not  finished  until  the  last  side
  77.      equals the first side:  eg 1,7,6,14,13,4,2,1 would be a 7 sided polygon.
  78.      The constant maxsurfaces determines the  maximum number  of  surfaces an
  79.      object can have.  The constant maxpolys determines the maximum number of
  80.      connections a surface can have.
  81.  
  82.      Sample shape data:
  83.  
  84.      headerthing dd -1   ; distance that first resolution is visable, -1 = last
  85.                  dd offset thing - offset $ - 4
  86.  
  87.      thing  dw 6        ; number of points
  88.             dw 4        ; number of surfaces
  89.             dw 25 dup (?) ; future use
  90.  
  91.             dw x,y,z    ; point 0
  92.             dw x,y,z    ; point 1
  93.             dw x,y,z
  94.             ...
  95.  
  96.             dw command
  97.             dw texture for side 1
  98.             dw texture for side 2
  99.             dw colour for side 1
  100.             dw colour for side 2
  101.             dw connection data eg (1,2,3,4,1)
  102.             dw [?,?,?] [optional surface normal if shade command used]
  103.             dw more connection data...
  104.             ...
  105.  
  106.     There are several  commands  one can use for each surface.  Commands like
  107.     steel texture, always visible, opposite  colours,  etc.  View the objects
  108.     include file to see what/how to use them.
  109.  
  110.     Bitmaps can be part of an object or be made as seperate  objects.  I will
  111.     be using the  bitmaps  for  things  like  explosions, smoke (from damaged
  112.     planes/spaceships) and distant suns/solar system (U know, like in x-wing)
  113.     set the values bitx and bity to the  scaling  to  be used for each bitmap
  114.     and set userotate to himap as this  is the command to define  a  bitmaped
  115.     object.  vxs and  vys  are  the  additional  scaling  used for individual
  116.     objects (vxs+bitx = final scaling factor).  When part  of an object,  use
  117.     dw himap/lomap, point #, x scale, y scale.  Remember, scaling is added to
  118.     bitx and bity so objects have a base scale plus some individual scale.
  119.  
  120.     Complex objects don't cut it for speed!  keep your objects simple and you
  121.     can have more of them on screen at once!  maximum speed is found with low
  122.     resolutions.  High resolutions with clipped borders also provide adaquate
  123.     speed.  A shallow but wide screen (small y, big x) provides  better usage
  124.     of cpu time  than  a  tall  and thin screen.  One big object is faster to
  125.     compute than many small objects (if  same  surface area) an object viewed
  126.     from the  side  takes signifiganly less time to compute  than  if  viewed
  127.     from the top  due  to  the shallow y, large x idea.   Object  shapes have
  128.     abcd prefixes.  Therefore,  as  object  gets  farther from  camera,  less
  129.     points/surface must be calculated.  You  must  define  shapes  for  every
  130.     distance.   You can have only one distance/shape if you want or  you  can
  131.     have hundreds.
  132.  
  133.        eg dd distance1
  134.           dd offset thing1 - offset $ - 4
  135.           dd distance2
  136.           dd offset thing2 - offset $ - 4
  137.           dd -1                            ; <- -1 is last distance flag
  138.           dd offset thing3 - offset $ - 4
  139.  
  140.     Surface data must be entered counter clockwize so side  will be  visible.
  141.     Clockwize surfaces are  visible  from  other side and will not be plotted
  142.     (unless you use a surface command override, see objects.inc)
  143.  
  144.     An increase in screen objects increases  cpu time.  However, if you  know
  145.     that you will always have the screen filled (in the case  of  floors, and
  146.     runways.) You can  disable  the clear_fill routine during those parts! if
  147.     the screen will be covered with background  walls  and  such, there is no
  148.     purpose to call  the  clear  routine to compute the next  part!   i  have
  149.     therefore added a  flag  for  the  clear_fill  routine  to use: when your
  150.     animation comes to the part when your looking at the ground or walls (and
  151.     there are NO empty spaces) toggle the  flag  to  skip  clear_fill and get
  152.     more  cpu  time.   This also works if you are approaching  an  object  or
  153.     large surface, since  the  new object will totaly cover the previous one.
  154.     Another time trick is to have your main background object include the sky
  155.     (or area to be cleared) as part of the  object.  If you are going to have
  156.     walls that go  halfway  up  the  screen,  have them go halfway  with  the
  157.     regular walls and then make another surface that goes to the top  of  the
  158.     screen (or above  if you want to move around) with the colour 0.  You can
  159.     then deactivate the  clear_fill routine  and  still  have  the  animation
  160.     appear as if the walls are completely seperate objects.
  161.  
  162.     Sorting routine for objects (as opposed to sides) uses  last  z  value to
  163.     re-sort for the  next  plot.   If you plan on drawing static pictures you
  164.     may want to call makobjs twice to: 1)  draw  and find zeds, sort, then 2)
  165.     re-draw. This will be the only way (and easiest way) to  plot an accurate
  166.     picture of what   we   have.  Don't  worry  about  calling  twice  during
  167.     animations as the first picture will  be  the  only  picture  that is not
  168.     sorted.  During animations,  all  objects are sorted properly,  based  on
  169.     previous z.
  170.  
  171.     Routines which are  expected to be used in animations have been optimized
  172.     but routines intended for use as background  and  title draw routines are
  173.     not intended to be fast.
  174.  
  175.      PLEASE DOCUMENT YOUR CHANGES!!
  176.  
  177.     Newfollow routine does  not  handle  object  lock on well  if  object  is
  178.     accelerating.  The routine  calculates  where  the  object  will be in di
  179.     frames and attempts to point the camera  to it in di frames.  However, if
  180.     the object is  accelerating, then the object will not  be  where  it  was
  181.     expected to be  at  that  time.   So  the  camera  must re-lock on to its
  182.     target.  This loop commences until the  camera  actually has locked on to
  183.     the target object, from this point on, the camera will  follow the object
  184.     regardless of motion.   The  re-lock on sequence takes the last number of
  185.     frames and divides it by two, so the re-lock on loop will move toward  an
  186.     accelerating object at an accelerating rate.
  187.  
  188.     General overview: locations are 32  bit  -2.1Gig  to  +2.1Gig, angles are
  189.     16bit from 0-65535 degrees, 4 quadrants - 4096 entries each quadrant.
  190.  
  191.     Variables in vector routine are 16bit.  cosine and sine  list  are  words
  192.     but get converted into doublewords when used.
  193.  
  194.      Some public routines: (not all, just some) See the top of the .asm files
  195.                            for complete lists of public routines.
  196.  
  197.   arctan           +/*% arctan(rise/run)=arctan(cx/ax).  any quadrant, 16bit
  198.   calc_angles      +/*% calculate xy angles between object di and object si
  199.   calc_middle      +/*% calculate xy angles between object di and ebx,ecx,ebp
  200.   checkfront       +/*% test points (di,bp) (si,qds) (dx,qes) for clockwize
  201.   clear_fill       +/   clears write page using xupdate and yupdate variables
  202.   compound         + *% compounds  angles  of eye and angles of object into
  203.                         matrix
  204.   cosine           +/*% eax=cos(eax), 16bit input, 32bit output
  205.   drawvect         +    draw list of vectors using points, sides and order
  206.   erotate          +/*% rotate for angles of eye, 32bit, uses ematrix
  207.   fakedraw         +/   draw line in firstbyte  and  lastbyte tables from xy1
  208.                         to xy2
  209.   flip_page        +/   flip between pages 0 and 1, wait for vertical sync
  210.   get_displacement +/*% calculate difference between objects
  211.   initfont        #     initialize font pointers
  212.   initpages       #     initialize x-mode pages for flip_page to page 0
  213.   loadpoints       + *% load points into array, rotate and translate as we go
  214.   loadsurfs        + *  load surfaces, check if visible as we go
  215.   look_at_it       +/*  immediatly  force  eyeax, eyeay to  look  at  object
  216.                         wherelook
  217.   make1obj         + *  make object si
  218.   make3d           +/*% make bx,cx,bp into bx,cx 2d pair, 16bit
  219.   makeobjs         +    make all objects then sorts based on last z location
  220.   move_to         # /*  move object si to bx,cx,bp - time di frames
  221.   newfollow       # /*  forces camera to follow object si, time to get there
  222.                         di
  223.   poly_fill        +/   uses oney,firstbyte and lastbyte to draw one surface
  224.   point_it         +/*  point object si at object di
  225.   point_dir        +/*  point object si in direction it is moving
  226.   point_to         +/*  point object si at location ebx,ecx,ebp
  227.   set_speed        +/*  calculate velocity based on angles
  228.   point_time       +/*  point obj di to bx,cx,bp in di frames
  229.   put_object       +/*  put object esi at location ebx,ecx,ebp
  230.   re_sort          +    sorts objects based on "finalzed" values
  231.   rotate           +/*% rotate bx,cx,bp (x,y,z) through matrix vrotate, 16bit
  232.   set_finall       +/*  calculate xsfinal for object (location)
  233.   set_finala       +/*  calculate vxsfinal for object (angles)
  234.   setmakeorder    #     resets order for makeobjs - for initialization
  235.   setsincose       +/   set sin and cos multipliers for eye rotations
  236.   setupbase       #     set up object base pointers to shapes
  237.   set_object_on     /*  turn object si on
  238.   set_object_off    /*  opposite
  239.   sine             +/*% ax=sin(ax), 16bit input, 32bit output
  240.   show_stars       +/   display stars in background
  241.   sort_list        +    sorts list of sides of polygon
  242.   twist_si         +/*  set angular velocity based on ebx,ecx,ebp and di(time)
  243.   updvectors       +/   updates vector xyz's and angles
  244.   where_si         +/*% return location of where object will be in di frames
  245.  
  246.      Legend:
  247.  
  248.        # used for initialization of code or new scene
  249.        + used regularly in animation loop
  250.        / can be used by user outside of animation loop if needed
  251.        * routine requires parameters passed in registers
  252.        % routine exits with results in registers
  253.        > routine wipes harddrive
  254.  
  255.     There are more routines at the end of  3d.asm  for more general functions
  256.     like find the camera displacement and finding rotational  offsets between
  257.     two objects.  U figure them out - fairly self explanatory. Also check out
  258.     poly.inc for more 3d functions and math.inc for general math functions.
  259.  
  260.     Drawvect  routine has a seperate routine for drawing lines (as opposed to
  261.     surfaces).  The fake_line  routine and poly_fill routine could do the job
  262.     but they were too slow.  The line was drawn twice then filled just like a
  263.     polygon but now a seperate routine clipps  and  draws.  If you  need/want
  264.     to use this line  drawing  routine  it  has   been   seperated  from  the
  265.     draw_vect  routine.  I  do  not use the xmode line draw by Matt Pritchard
  266.     as it does not allow for clipping.
  267.  
  268.     Sin and cosin tables - 90 degrees is 16384, 180=32768...
  269.  
  270.     Move_si routine - to move an object around, load up ebx, ecx and ebp with
  271.     the x,y,z locations of where you want the object to end up.  Load di with
  272.     the time you would like the object to take to get there. Load si with the
  273.     object number you want to move and call  move_si.  The updvectors routine
  274.     does the rest!
  275.  
  276.     To look at an object.  either 1) put the object number  in  wherelook. or
  277.     2) load si  with the object to look at, load di with the time to move the
  278.     camera to the object, and call new_follow.
  279.  
  280.     Just think, only  7 months ago (march '93), i had trouble  programming  a
  281.     batch file!
  282.  
  283.   Shape data can be almost as large as you need it 'till it crashes. try a cube
  284.   20000x20000x20000.    Calculations  use  32  bit  registers  and  can  handle
  285.   up to 16 bit locations.  keeping the object size small will  allow  a  larger
  286.   visible space.  but larger objects will allow you to  get  closer  with  more
  287.   accuracy in the mathematics of rotations.
  288.  
  289.   List of command bits to date: (for object definitions)
  290.  
  291.   note: "visible" = "points appear counter-clockwise"
  292.  
  293.   texture definitions:
  294.  
  295.     0       - normal surface, no features, constant colour.
  296.     wavey   - steel texture for surface 0 = none,  colour  offset  determines
  297.               screen offset for texture.  eg 16+7 will use colour block 16-31
  298.               but make the sine wave texture 14 (7*2) lines down. this is  so
  299.               all sine wave textures do not appear on the same line.
  300.               windows and engines look good with this feature.
  301.     shade   - lambert shading bit, must have normal calculated or  at  least
  302.               have    free    space     for    pre_cal_lambert    to    use:
  303.               eg 128,16*1,1,2,3,1, ?,?,?<- these 3 words are surface normal!
  304.     inverse - inversion bit for shading option.  0=normal shading, 1=inverse
  305.               if option +4  is used, inversion  automatically  occures  when
  306.               other side is displayed.
  307.     glow    - =shade+inverse
  308.     last    - colour has same colour as previous surface (used when
  309.               you want gourad shading, but want to avoid  duplicate
  310.               calculations - don't set gourad bit if this  is  what
  311.               you use it for.) when this is used, the colour number
  312.               determines the new colour block to use.  the  shading
  313.               of this colour will be the same as the surface before
  314.               it, but the colour block can be different.
  315.     mesh    - screen door style of surface
  316.     stone   - texture map style surface, I just liked the way it looked..
  317.     glenz   - glenz vector surface - uses cross referancing palette for
  318.               changing on screen colours.
  319.  
  320.   commands:
  321.  
  322.     point   - defines a single point; must be repeated! eg dw 64,col,3,3
  323.     line    - if used, defines a line (must be set to define a true line)
  324.     himap   - if set, defines a bitmap,eg: point #, bitmap #, x scale,y scale
  325.     lomap   - uses 1/4 scaled bitmap (every 4'th pixel is sampled), fast
  326.  
  327.     iterate - generate iteration if side visible (iteration = sub-object)
  328.  
  329.     both    - side is always visible no matter angle, skips counter-clowise test
  330.             - "both sides have same texture"
  331.     double  - side is always visible but other side has high byte colour
  332.               "double sided surface"
  333.               note: if this is used, option "both" must not be used!!
  334.     onscr   - test if side is on screen - don't use if all points are
  335.               outside clipping parameters.
  336.     check   - dont plot this side, just use as test points for visibility.
  337.               this is mostly used with iterations.
  338.     matrix  - generate new matrix
  339.     sub-object - make subobject
  340.     gosub      - transfer loading of surface data elsewhere
  341.     return     - return from gosub
  342.  
  343.  
  344.   There are a kazillion more options - look in the  objects.inc  file  for  the
  345.   surface types and example objects.
  346.  
  347.   There are two kinds of bitmaps and points.  Those which  are  inside  objects
  348.   and those which are seperate objects themselves. if userotate object  command
  349.   is set to himap/point,then  the  entire  object  is  considered  as  a  point
  350.   or bitmap.  But if userotate is not set this way, then  a  normal  object  is
  351.   drawn and bitmaps then come from within the object definitions (below).  this
  352.   way, bitmaps and points can be either part of a larger object,  or  they  are
  353.   computed fast on their own. (eg explosions and bullets as  seperate  objects)
  354.  
  355.   Note: When writing surface descriptions, try to make the  first value unique
  356.   from any other first value.  this way, the sort routine  will  give  a  more
  357.   accurate sorting of sides. eg 1,3,6,1  2,4,1,2  rather than 1,3,6,1  1,2,4,1
  358.  
  359.   to recap:
  360.  
  361.          0 = constant colour, only visible from counter-clockwise side
  362.      wavey = sine texture
  363.      shade = shading - requires 3 blank words for surface normal eg dw 0,0,0
  364.    inverse = invert the shading direction, 0=normal, 1=sun is other way.
  365.       last = use intensity from previous surface (not colour, only intensity)
  366.      point = point
  367.       line = line
  368.      himap = bitmap (scalable, non-rotatable)
  369.      lomap = bitmap (scalable, non-rotatable)
  370.    iterate = generate iteration if side visible
  371.       both = always visible
  372.     double = always visible but other side has high byte colour,"double sided"
  373.      onscr = plot side only if all the following points are on the screen
  374.      check = dont plot side but use the following points as a test for visiblity
  375.  
  376.   What you can't mix on a single surface: "double" with "both"!!
  377.  
  378.   You do not have to define a point for the center of the  object.  the  point
  379.   0 defines the center of the object.  This is different from earlier versions
  380.  
  381.   Remember that negative y (-y) is up, +y is down.  This is opposite  from our
  382.   regular grade 13 mathematics but it is consistant with the computers  screen
  383.   arrangement.  If your objects look funny, make sure you have this correct.
  384.  
  385.   The shading for objects requires that 3  words be  present  after  the  side
  386.   definition.  These 3 words represent the surface normal to the side and  can
  387.   be either set by you (slow and tedious) by using the normal.bas program,  or
  388.   can be set up by the routine pre_cal_lambert.  This routine scans the object
  389.   to find surfaces that have the shading bit set (128).   The  surface  normal
  390.   will be calculated for that surface and stored in the 3 words set  aside  by
  391.   you.  If you remove the shading feature from a surface, make sure you remove
  392.   the extra 3 words or it will screw up.  But you knew that right.  To use the
  393.   routine pre_cal_lambert, load si with the object you wish to scan, and call.
  394.   make sure objbase points to the offset of the object.  si will be the object
  395.   number, eg 0,1,2,3, not the offset. The offset will come from objbase.
  396.  
  397.   Each on-screen object can have it's own colour palette scheme by setting the
  398.   palxref offsets to a cross reference palette.  this uses the xlat command to
  399.   take the objects colour, and xlat it into a new colour  based  on  the  xref
  400.   table you provide.  each object can have it own xref table.  This way,  many
  401.   on-screen objects can use the same shape data while each is coloured  with a
  402.   different colour scheme (5 stuka  airplanes  all  coloured  differently, for
  403.   example)  You will find the palxref tables (for each object remember) in the
  404.   file equ.inc.  A routine set_xref_palette has been provided for you  so  you
  405.   can set the xref offset (this routine is in poly.inc)
  406.  
  407.   To have a bitmap on the screen (scalable but non-rotatable) use option himap
  408.   in either userotate or as an object command.  Lomap  uses  the  same  bitmap
  409.   method but only draws every 4'th pixel - good for explosions and smoke.
  410.  
  411.   onoff commands:
  412.  
  413.   0 = object off          eg mov onoff[esi],2  ; turn on sub object
  414.   1 = main object on
  415.   2 = sub object on
  416.  
  417.   userotate object commands:
  418.  
  419.   0  = all rotations supported - full object
  420.  
  421.   1  = camera rotations only - no compound, new loadpoints
  422.  
  423.       object is same as when userotate=0 but will not allow any object specific
  424.       rotations.  this is used to speed up rendering of objects that are
  425.       stationary or objects that will always be pointing in the same direction.
  426.       make1obj routine then assumes angles = 0x, 0y, 0z
  427.  
  428.       if this is used to define a sub-object (see main.asm for that green box
  429.       with those two sub-object blocks) then +1 option in userotate makes the
  430.       box angle/rotation independant from the main object.
  431.  
  432.   himap = bitmap - no compound, no loadpoints, no sort and no drawvect
  433.   lomap = bitmap, 1/4 scale, faster than 32
  434.  
  435.       if object is bitmap, then:
  436.  
  437.       whatshape - indexer to which bitmap in bitbase list
  438.       xs,ys,zs  - point to bitmap location in space
  439.       vxs       - bitmap scaling (how big is bitmap).  note: bitmap is already
  440.                   scaled based on distance so you don't have to change this
  441.                   as the bitmap gets farther away.
  442.  
  443.   point = point - no compound, no loadpoints, no sort and no drawvect
  444.  
  445.       used for bullets.  could be used for stars but if you do  want  to  make
  446.       stars, make a specialized bitmap routine.  making stars as objects would
  447.       be too slow.  right now, bullets all have same colour, see  constant  in
  448.       equ.inc.  note:sept 29/93, stars routines now are a seperate specialized
  449.                      assembley routine. - stars.asm
  450.  
  451.       xs,ys,zs  - point to bullet location in space
  452.  
  453.   The locations of sub_objects are x/256 because of the way conversion between
  454.   real space co-ordinates and object co-ordinates  are   calculated.   Objects
  455.   are 256 times larger than their appearance in real space. This  allows  much
  456.   greater  accuracy  in  real  space!!    Eg ,  if  you have a  cube  500x500x
  457.   500 (which is really 1000 wide cause -500 to +500 is 1000  units)  then,  in
  458.   order to "move" accros the surface, you should only have to move 1000 units,
  459.   right?  Well here, you'll have to move 256000 units even though the cube  is
  460.   only 1000 units wide/tall/deep.  This is because the real space co-ordinates
  461.   are 24 bit (32bit/256).  This gives you greater accuracy in placing  objects
  462.   where you want them in space but still allows you to have very large objects
  463.  
  464.   If your objects appear jittery when viewing close-up, make  them  physically
  465.   larger.  For example, double all the point  data  (makes  object  twice  the
  466.   size).  This way, the multiply routine has more  accuracy  when  calculating
  467.   rotations/3dpoints.
  468.  
  469.   Example of how to draw a single polygon:
  470.  
  471.            p1x equ -50
  472.            p1y equ -50
  473.            p2x equ -90
  474.            p2y equ 70
  475.            p3x equ 60
  476.            p3y equ 80
  477.  
  478.            mov x1,p1x
  479.            mov y1,p1y
  480.            mov x2,p2x
  481.            mov y2,p2y
  482.            call fakeline  ; draw in buffer
  483.  
  484.            mov x1,p2x
  485.            mov y1,p2y
  486.            mov x2,p3x
  487.            mov y2,p3y
  488.            call fakeline  ; draw in buffer
  489.  
  490.            mov x1,p3x
  491.            mov y1,p3y
  492.            mov x2,p1x
  493.            mov y2,p1y
  494.            call fakeline  ; draw in buffer
  495.  
  496.            mov colq,7
  497.            mov steel,-1
  498.            call poly_fill ; fill polygon on screen
  499.  
  500.            call flip_page ; show it...
  501.  
  502.  
  503.   A little note about polygon construction:
  504.  
  505.    Polygons can only have angles less than 180 degrees. That is, they must be
  506.    round like circles, not hooky like a sickle.  eg:
  507.  
  508.                          /\
  509.    /\                    \ \ invalid polygon
  510.    \ \ valid polygon     /  \
  511.     \ \                  \/\ \
  512.      \/                     \/
  513.                            ^
  514.                            |---------this angle is greater than 180degrees.
  515.  
  516.   if you want to make this here^^^^, you must split it up into 2:
  517.                       /\               /\
  518.                       \ \              \ \
  519.           /\     +     \ \      =      /  \
  520.           \/            \ \            \/\ \
  521.                          \/               \/
  522.  
  523.    So, an object like so:    ____
  524.                             / __ \
  525.                            /_/  \_\
  526.  
  527.    must be drawn like so:
  528.                 ____       ____
  529.      /\ + /\  + \__/   =  / __ \
  530.     /_/   \_\            /_/  \_\
  531.  
  532.  
  533.   Question:  How come my objects appear upside-down
  534.   Answer: Thats because the Y axis is inverted.  Positive X points to the
  535.           right, positive Z points away from you and positive Y points down.
  536.  
  537.   Question: Ok, I make the Y value point down, now they still don't look
  538.             right - the surfaces are connected correctly but it looks wrong.
  539.   Answer: The most probable reason for this type of error is that the
  540.           connection data has been entered in reverse order.  Eg 3,4,5,2,7,3
  541.           should probably have been entered as 3,7,2,5,4,3. Remember, enter
  542.           the surfaces in Counter-Clock-Wise order.
  543.  
  544.   If you don't like manual data entry (which I don't)  you  can  try  out the
  545.   converter DXF23DV which should be supplied with this package. Now just draw
  546.   your objects in AutoCAD and it will convert them into assembley connections
  547.   Remember, in AutoCAD +z points up, +y point away, in my package, +z  points
  548.   away, +y points down.  Draw the objects in Autocad as if +z is  up  and  my
  549.   converter will change the co-ordinate system for you.
  550.  
  551.   Question: The objects look great from far away, but up  close,  the  appear
  552.             "jumpy" or the whole thing disappears.
  553.   Answer: Your using too small a scale factor.  If you have a cube  10x10x10,
  554.           the math routines dont have much room to calculate a rotated object
  555.           Try making your objects bigger, like  1000x1000x1000.   The  reason
  556.           why the entire object may disappear is  that  the   center  of  the
  557.           object has passed to close  to  the  camera.   If  you  have  large
  558.           objects, you may want to cut them up  into  seperate  sections  and
  559.           piece them together as a seperate objects.
  560.  
  561.  
  562.  
  563.  
  564.